import type { AxiosRequestConfig } from 'axios';
import axios from 'axios';
import qs from 'qs';
import { message } from 'antd';

axios.defaults.baseURL = '/';
axios.defaults.timeout = 60000;
axios.defaults.withCredentials = true;

const messageKey = 'msgKey';

interface RequestConfig extends AxiosRequestConfig {
  baseurlType?: string;
  config?: any;
  serverType?: any;
  loading?: boolean;
  useSelfDead?: any;
  headers?: any;
}

interface Params {
  params?: any;
  data?: any;
  loading?: boolean;
  serverType?: any;
}

axios.interceptors.request.use(
  (config: RequestConfig): RequestConfig => {
    if (!config.useSelfDead) {
      config.headers['Content-Type'] = 'application/json;charset=UTF-8';
    }

    let authorization = sessionStorage.getItem('token');
    if (authorization) {
      config.headers['token'] = authorization;
    }
    config.headers['source'] = 'backend';
    return config;
  },
  (err) => {
    return Promise.reject(err);
  },
);

axios.interceptors.response.use(
  (res: any) => {
    let response = res.data;
    if (response.success) {
      if (response.data?.token) {
        sessionStorage.setItem('token', response.data?.token);
      }
      return Promise.resolve(response && response.data);
    } else if (response.code === 302) {
      return Promise.reject(res);
    } else if (response.code === 401) {
      return Promise.reject(res);
    } else if (
      res.status === 200 &&
      !response.success &&
      response.errorMessage
    ) {
      message.error({ content: response.errorMessage, key: messageKey }).then();
      if (response?.errorCode === 'NOT_LOGIN') {
        sessionStorage.clear();
        window.open('/frontend-web/index.html#/wrapper/login', '_self');
      }
      return Promise.reject(res);
    } else if (res.status === 200) {
      return Promise.resolve(res.data);
    } else {
      return Promise.reject(res);
    }
  },
  (error: any) => {
    if (error && error.response && error.response.data) {
      let data = error.response.data;
      if (data.code === 401) {
        window.open('/#/login', '_self');
      } else {
        message
          .error({
            content: error.response.data.msg ? error.response.data.msg : '错误',
            key: messageKey,
          })
          .then();
      }
    }

    return Promise.reject(error.response);
  },
);

function get(url: string, config?: AxiosRequestConfig): Promise<any> {
  return new Promise((resolve, reject) => {
    axios
      .get(url, {
        ...config,
        // 手动将数组序列化的模式设置为repeat
        paramsSerializer(params) {
          return qs.stringify(params, { arrayFormat: 'repeat' });
        },
      })
      .then((response) => {
        resolve(response);
      })
      .catch((err) => {
        reject(err);
      });
  });
}

function post(url: string, config: Params = {}): any {
  const { data, ...rest } = config;
  return new Promise((resolve, reject) => {
    axios
      .post(url, data, {
        ...rest,
        paramsSerializer(params) {
          return qs.stringify(params, { arrayFormat: 'repeat' });
        },
      })
      .then(
        (response) => {
          resolve(response);
        },
        (err) => {
          reject(err);
        },
      );
  });
}

function patch(url: string, config: Params) {
  return new Promise((resolve, reject) => {
    axios.patch(url, config).then(
      (response) => {
        resolve(response);
      },
      (err) => {
        reject(err);
      },
    );
  });
}

function put(url: string, config: Params) {
  const { data, ...rest } = config;
  return new Promise((resolve, reject) => {
    axios
      .put(url, data, {
        ...rest,
        // 手动将数组序列化的模式设置为repeat
        paramsSerializer(params) {
          return qs.stringify(params, { arrayFormat: 'repeat' });
        },
      })
      .then(
        (response) => {
          resolve(response);
        },
        (err) => {
          reject(err);
        },
      );
  });
}

function del(url: string, config?: Params) {
  return new Promise((resolve, reject) => {
    axios
      .delete(url, config)
      .then((response) => {
        resolve(response);
      })
      .catch((err) => {
        reject(err);
      });
  });
}

export { get, post, put, patch, del };

export default axios;
